using AutoMapper;
using MediatR;
using Microsoft.Extensions.Logging;
using RBAC.Domain.SalesManage;
using RBAC.ErrorCode;
using RBAC.Interstructrue.Base;
using RBAC.Write.Api.Application.Command.ERP.SalesManagement;
using System.Data;
using System.Text;
using ClosedXML.Excel;
using System.IO;

namespace RBAC.Write.Api.Application.Handler.ERP.SalesManagement
{
    /// <summary>
    /// 导出销售订单处理器
    /// </summary>
    public class ExportSalesOrderHandler : IRequestHandler<ExportSalesOrderCommand, APIResult<byte[]>>
    {
        private readonly IBaseRepository<SalesOrder> salesOrderRepository;
        private readonly ILogger<ExportSalesOrderHandler> logger;
        private readonly IMapper mapper;

        public ExportSalesOrderHandler(IBaseRepository<SalesOrder> salesOrderRepository,
            ILogger<ExportSalesOrderHandler> logger,
            IMapper mapper)
        {
            this.salesOrderRepository = salesOrderRepository;
            this.logger = logger;
            this.mapper = mapper;
        }

        /// <summary>
        /// 处理导出销售订单请求
        /// </summary>
        /// <param name="request">导出请求</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>Excel文件字节数组</returns>
        public Task<APIResult<byte[]>> Handle(ExportSalesOrderCommand request, CancellationToken cancellationToken)
        {
            APIResult<byte[]> result = new APIResult<byte[]>();

            try
            {
                logger.LogInformation("开始导出销售订单数据，页码：{PageIndex}，每页数量：{PageSize}，导出全部：{ExportAll}", 
                    request.PageIndex, request.PageSize, request.ExportAll);

                // 验证分页参数
                if (request.PageSize > 10000 && !request.ExportAll)
                {
                    result.Code = APIEnums.Error;
                    result.Msg = "单次导出数量不能超过10000条，如需导出更多数据请设置ExportAll=true或分批导出";
                    return Task.FromResult(result);
                }

                // 构建查询条件
                var whereClause = BuildWhereClause(request);
                var parameters = BuildParameters(request);

                // 执行查询（根据是否导出全部数据选择不同的查询方式）
                IEnumerable<SalesOrder> data;
                if (request.ExportAll)
                {
                    // 导出全部数据，不分页
                    data = salesOrderRepository.GetAll(whereClause, parameters);
                    logger.LogInformation("导出全部数据，共 {Count} 条记录", data?.Count() ?? 0);
                }
                else
                {
                    // 分页导出
                    var pagedResult = salesOrderRepository.GetPaged(request.PageIndex, request.PageSize, whereClause, request.OrderBy, parameters);
                    data = pagedResult.Data;
                    logger.LogInformation("分页导出数据，第 {PageIndex} 页，每页 {PageSize} 条，共 {Count} 条记录，总记录数 {TotalCount}", 
                        request.PageIndex, request.PageSize, data?.Count() ?? 0, pagedResult.TotalCount);
                }

                if (data == null || !data.Any())
                {
                    result.Code = APIEnums.Error;
                    result.Msg = "没有符合条件的数据可导出";
                    return Task.FromResult(result);
                }

                // 创建DataTable
                DataTable dt = new DataTable("销售订单");
                dt.Columns.Add("订单编码", typeof(string));
                dt.Columns.Add("单据类型", typeof(string));
                dt.Columns.Add("单据日期", typeof(string));
                dt.Columns.Add("单据状态", typeof(string));
                dt.Columns.Add("审批日期", typeof(string));
                dt.Columns.Add("审批员", typeof(string));
                dt.Columns.Add("客户名称", typeof(string));
                dt.Columns.Add("收货人", typeof(string));
                dt.Columns.Add("电话", typeof(string));
                dt.Columns.Add("地址", typeof(string));
                dt.Columns.Add("业务类型", typeof(string));
                dt.Columns.Add("业务状态", typeof(string));
                dt.Columns.Add("销售部门", typeof(string));
                dt.Columns.Add("销售人员", typeof(string));
                dt.Columns.Add("销售类型", typeof(string));
                dt.Columns.Add("供货方式", typeof(string));
                dt.Columns.Add("交货日期", typeof(string));
                dt.Columns.Add("创建时间", typeof(string));
                dt.Columns.Add("创建人", typeof(string));

                // 填充数据
                foreach (var order in data)
                {
                    DataRow row = dt.NewRow();
                    row["订单编码"] = order.OrderCode ?? "";
                    row["单据类型"] = order.OrderType ?? "";
                    row["单据日期"] = order.OrderDate.HasValue ? order.OrderDate.Value.ToString("yyyy-MM-dd") : "";
                    row["单据状态"] = order.OrderStatus ?? "";
                    row["审批日期"] = order.AuditDate.HasValue ? order.AuditDate.Value.ToString("yyyy-MM-dd") : "";
                    row["审批员"] = order.Auditor ?? "";
                    row["客户名称"] = order.CustomerName ?? "";
                    row["收货人"] = order.Receiver ?? "";
                    row["电话"] = order.Phone ?? "";
                    row["地址"] = order.Address ?? "";
                    row["业务类型"] = order.BusinessType ?? "";
                    row["业务状态"] = order.BusinessStatus ?? "";
                    row["销售部门"] = order.SalesDepartment ?? "";
                    row["销售人员"] = order.SalesPerson ?? "";
                    row["销售类型"] = order.SalesChannel ?? "";
                    row["供货方式"] = order.SupplyMode ?? "";
                    row["交货日期"] = order.DeliveryDate.HasValue ? order.DeliveryDate.Value.ToString("yyyy-MM-dd") : "";
                    row["创建时间"] = order.CreateTime.ToString("yyyy-MM-dd HH:mm:ss");
                    row["创建人"] = order.CreateUser ?? "";
                    dt.Rows.Add(row);
                }

                // 导出为Excel
                byte[] fileBytes = ExportToExcel(dt);

                result.Code = APIEnums.Success;
                result.Msg = "导出销售订单成功";
                result.Data = fileBytes;

                logger.LogInformation("销售订单导出成功，共导出{Count}条记录", data.Count());
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "销售订单导出失败：{Message}", ex.Message);
                result.Code = APIEnums.Error;
                result.Msg = "导出销售订单失败：" + ex.Message;
            }

            return Task.FromResult(result);
        }

        /// <summary>
        /// 构建WHERE查询条件
        /// </summary>
        /// <param name="request">查询请求</param>
        /// <returns>WHERE条件字符串</returns>
        private string BuildWhereClause(ExportSalesOrderCommand request)
        {
            var conditions = new List<string>();

            if (!string.IsNullOrEmpty(request.OrderCode))
            {
                conditions.Add("OrderCode LIKE @OrderCode");
            }

            if (!string.IsNullOrEmpty(request.CustomerName))
            {
                conditions.Add("CustomerName LIKE @CustomerName");
            }

            if (!string.IsNullOrEmpty(request.OrderStatus))
            {
                conditions.Add("OrderStatus = @OrderStatus");
            }

            if (!string.IsNullOrEmpty(request.BusinessStatus))
            {
                conditions.Add("BusinessStatus = @BusinessStatus");
            }

            if (request.StartDate.HasValue)
            {
                conditions.Add("OrderDate >= @StartDate");
            }

            if (request.EndDate.HasValue)
            {
                conditions.Add("OrderDate <= @EndDate");
            }

            if (!string.IsNullOrEmpty(request.SalesPerson))
            {
                conditions.Add("SalesPerson LIKE @SalesPerson");
            }

            return conditions.Count > 0 ? string.Join(" AND ", conditions) : "";
        }

        /// <summary>
        /// 构建查询参数
        /// </summary>
        /// <param name="request">查询请求</param>
        /// <returns>查询参数字典</returns>
        private object BuildParameters(ExportSalesOrderCommand request)
        {
            var parameters = new Dictionary<string, object>();

            if (!string.IsNullOrEmpty(request.OrderCode))
            {
                parameters["OrderCode"] = $"%{request.OrderCode}%";
            }

            if (!string.IsNullOrEmpty(request.CustomerName))
            {
                parameters["CustomerName"] = $"%{request.CustomerName}%";
            }

            if (!string.IsNullOrEmpty(request.OrderStatus))
            {
                parameters["OrderStatus"] = request.OrderStatus;
            }

            if (!string.IsNullOrEmpty(request.BusinessStatus))
            {
                parameters["BusinessStatus"] = request.BusinessStatus;
            }

            if (request.StartDate.HasValue)
            {
                parameters["StartDate"] = request.StartDate.Value.Date;
            }

            if (request.EndDate.HasValue)
            {
                parameters["EndDate"] = request.EndDate.Value.Date.AddDays(1).AddSeconds(-1); // 包含结束日期当天
            }

            if (!string.IsNullOrEmpty(request.SalesPerson))
            {
                parameters["SalesPerson"] = $"%{request.SalesPerson}%";
            }

            return parameters;
        }

        /// <summary>
        /// 导出DataTable为Excel
        /// </summary>
        /// <param name="dt">数据表</param>
        /// <returns>Excel文件字节数组</returns>
        private byte[] ExportToExcel(DataTable dt)
        {
            // 使用 ClosedXML 生成 XLSX
            using (var workbook = new ClosedXML.Excel.XLWorkbook())
            {
                var sheetName = string.IsNullOrWhiteSpace(dt.TableName) ? "Sheet1" : dt.TableName;
                var worksheet = workbook.Worksheets.Add(dt, sheetName);

                // 冻结首行（表头）
                worksheet.SheetView.FreezeRows(1);

                // 自动列宽
                worksheet.Columns().AdjustToContents();

                using (var ms = new System.IO.MemoryStream())
                {
                    workbook.SaveAs(ms);
                    return ms.ToArray();
                }
            }
        }
    }
}